#include "stdafx.h"
#include "Input.h"
#include "Mouse.h"
#include "Keyboard.h"
#include "ActionManager.h"


CInput::CInput()
{

}

CInput::~CInput()
{
	UnregisterListener(this);
	UnregisterListener(m_action_manager.get());
}

bool CInput::Init()
{
	m_mouse.reset(new CMouse);
	m_keyboard.reset(new CKeyboard);
	m_action_manager.reset(new CActionManager);

	RegisterListener(this);
	RegisterListener(m_action_manager.get());

	return true;
}

void CInput::Update()
{
	m_text.Render();
}

void CInput::RegisterListener(IInputListener* listener)
{
	m_mouse->RegisterListener(listener);
	m_keyboard->RegisterListener(listener);
}

void CInput::UnregisterListener(IInputListener* listener)
{
	m_mouse->UnregisterListener(listener);
	m_keyboard->UnregisterListener(listener);
}

void CInput::DispatchMessage(uint msg, WPARAM wParam, LPARAM lParam)
{
	if (msg == WM_INPUT && wParam == RIM_INPUT)
	{
		HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(lParam);
		
		RAWINPUT input;
		uint buffer_size = sizeof(RAWINPUT);
		GetRawInputData(hRawInput, RID_INPUT, &input, &buffer_size, sizeof(RAWINPUTHEADER));

		switch (input.header.dwType)
		{
		case RIM_TYPEKEYBOARD:
			m_keyboard->ProcessMessage(input.data.keyboard);
			break;

		case RIM_TYPEMOUSE:
			m_mouse->ProcessMessage(input.data.mouse);
			break;

		default:
			assert(!"Unsupported input device");
		}
	}
}

IMouse* CInput::GetMouse()
{
	return m_mouse.get();
}

IKeyboard* CInput::GetKeyboard()
{
	return m_keyboard.get();
}

IActionManager* CInput::GetActionManager()
{
	return m_action_manager.get();
}

void CInput::OnInputEvent(const SInputEvent& input_event)
{
	bool press = input_event.key_state == eKeyState_Pressed;

	char character = input_event.character ? input_event.character : '_';
	string text = string_utils::format("%c (%s)", character, press ? "pressed" : "released");
	m_text.SetText(text.c_str());
}